package com.rem.chat.controller;

import com.rem.chat.aop.annotation.GlobalInterceptor;
import com.rem.chat.common.constants.Constants;
import com.rem.chat.common.errcode.ControllerErrorCodeConstants;
import com.rem.chat.common.exception.ControllerException;
import com.rem.chat.common.utils.JacksonUtil;
import com.rem.chat.common.utils.RedisUtil;
import com.rem.chat.pojo.request.UserInfoSaveRequest;
import com.rem.chat.pojo.request.UserModifyPasswordRequest;
import com.rem.chat.pojo.response.CommonResult;
import com.rem.chat.pojo.response.GetUserInfoResponse;
import com.rem.chat.pojo.response.SearchUserInfoResponse;
import com.rem.chat.service.UserService;
import com.rem.chat.service.dto.UserLoginDTO;
import com.rem.chat.service.enums.UserContactStatusEnum;
import com.rem.chat.websocket.ChannelContextUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * @author: Themberfue
 * @date: 2025/6/8 20:13
 * @description:
 */
@RestController
@RequestMapping("/user")
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Resource
    RedisUtil redisUtil;

    @Resource(name = "userServiceImpl")
    UserService userService;

    @Resource
    ChannelContextUtil channelContextUtil;

    @GetMapping("/getUserInfo")
    @GlobalInterceptor
    public CommonResult<GetUserInfoResponse> getUserInfo(HttpServletRequest request) {

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        return CommonResult.success(
                userService.getUserInfo(user.getUserId()));
    }

    @PutMapping("/searchUserInfo")
    @GlobalInterceptor
    public CommonResult<SearchUserInfoResponse> searchUserInfo(HttpServletRequest request,
                                                               @NotEmpty String userId) {
        
        log.info("searchUserInfo userId:{}", userId);

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        return CommonResult.success(
                userService.searchUserInfo(user.getUserId(), userId));
    }

    @DeleteMapping("/delContact")
    @GlobalInterceptor
    public CommonResult<Boolean> delContact(HttpServletRequest request,
                                            @NotNull String userId) {
        
        log.info("delContact contactId:{}", userId);

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        return CommonResult.success(
                userService.removeContact(user.getUserId(), userId, UserContactStatusEnum.DEL));
    }

    @DeleteMapping("/addContact2BlackList")
    @GlobalInterceptor
    public CommonResult<Boolean> addContact2BlackList(HttpServletRequest request,
                                            @NotNull String userId) {
        
        log.info("addContact2BlackList contactId:{}", userId);

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        return CommonResult.success(
                userService.removeContact(user.getUserId(), userId, UserContactStatusEnum.BLACKLIST));
    }

    @PostMapping("/saveUserInfo")
    @GlobalInterceptor
    public CommonResult<GetUserInfoResponse> saveUserInfo(HttpServletRequest request,
                                                          @RequestPart @Valid UserInfoSaveRequest param,
                                                           MultipartFile avatarFile,
                                                          MultipartFile avatarCover) throws IOException {
        
        log.info("saveUserInfo UserInfoSaveRequest:{}", param);

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        // Step 校验是否由本人操作
        if (!user.getUserId()
                .equals(param.getUserId())) {
            throw new ControllerException(ControllerErrorCodeConstants.NOT_USER_OPERATE);
        }

        return CommonResult.success(
                userService.saveUserInfo(param, avatarFile, avatarCover));
    }

    @PostMapping("/modifyPassword")
    @GlobalInterceptor
    public CommonResult<Boolean> modifyPassword(HttpServletRequest request,
                                                @RequestBody @Validated UserModifyPasswordRequest param) {
        
        log.info("modifyPassword UserModifyPasswordRequest:{}", param);

        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        // Step 校验是否由本人操作
        if (!user.getUserId()
                .equals(param.getUserId())) {
            throw new ControllerException(ControllerErrorCodeConstants.NOT_USER_OPERATE);
        }

        // Step 强制退出，重新登录
        channelContextUtil.removeContext(user.getUserId());

        return CommonResult.success(
                userService.modifyPassword(user.getUserId(), param));
    }

    @PostMapping("/logout")
    @GlobalInterceptor
    public CommonResult<Boolean> logout(HttpServletRequest request) {
        // Step 获取用户 Token (拦截器已经提前处理，无需做过多校验)
        UserLoginDTO user = getUserLoginDTO(request);

        // Step 强制退出，重新登录
        channelContextUtil.removeContext(user.getUserId());

        return null;
    }

    private UserLoginDTO getUserLoginDTO(HttpServletRequest request) {
        String token = request.getHeader("token");
        String user = redisUtil.get(Constants.REDIS_KEY_WS_TOKEN + token);
        log.info("user: {}", user);
        return JacksonUtil.readValue(user, UserLoginDTO.class);
    }
}
